home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / Amiga_Mail_Vol2 / Archives / Plain / ja92 / Bullet / Bullet.txt < prev    next >
Encoding:
Text File  |  1992-08-18  |  28.4 KB  |  613 lines

  1. (c)  Copyright 1992 Commodore-Amiga, Inc.   All rights reserved.
  2. The information contained herein is subject to change without notice,
  3. and is provided "as is" without warranty of any kind, either expressed
  4. or implied.  The entire risk as to the use of this information is
  5. assumed by the user.
  6.  
  7. Using Compugraphic Typefaces with Bullet
  8.  
  9.  
  10. by John Orr
  11.  
  12.  
  13.  
  14. One of the improvements made to the Amiga's operating system for
  15. Workbench Release 2.1 is programmatic control of AGFA's IntelliFontÃ’
  16. scaling engine.  With this engine, application programs can fully
  17. utilize Compugraphic (CG) typefaces installed by Fountain (the CG
  18. typeface install that comes with 2.04 and 2.1).  Some of the features
  19. that the font scaling engine offers include:
  20.  
  21. o Rasterization of a typeface to arbitrary vertical and horizontal
  22.    resolutions.
  23. o Baseline rotation of glyphs to an arbitrary angle.
  24. o Glyph shearing (italicizing) to any angle from -45 to 45 degrees
  25.    (inclusive).
  26. o Access to kerning tables.
  27. o Algorithmic emboldening.
  28.  
  29.  
  30.  
  31. Starting the Engine
  32.  
  33. There are several steps involved in using a font outline on the Amiga.
  34.  
  35. 1. Open the font contents file (the ``.font'' file) and verify that
  36. it has a corresponding outline tag file (an ``.otag'' file).
  37.  
  38. All system supported fonts on the Amiga have a font contents file.
  39. From this file, an application can determine a font's type, so the
  40. application knows how to utilize the font.  The font contents file is
  41. a FontContentsHeader structure (defined in <diskfont/diskfont.h>).
  42. The first field of that structure (fch_FileID) contains an ID
  43. identifying the font's type.  If that type is OTAG_ID (0x0F03), the
  44. font is an outline and it should have a corresponding otag file.  The
  45. otag file should be in the same directory as the font contents file.
  46.  
  47. 2. Open the otag file, verify that it is valid, load its tag list
  48. into memory, and resolve any memory indirections in the tag list.
  49.  
  50. The otag file contains a tag list that describes the typeface.  All
  51. of these tags are defined in <diskfont/diskfonttag.h> as either level
  52. 1, level 2, or level 3 outline tags.  Level 1 tags are required to be
  53. present in an otag file.  Level 2 and 3 tags are optional.  See the
  54. include file for more information on the tag levels.
  55.  
  56. The first tag of the otag file is always OT_FileIdent.  Its value is
  57. the size of the otag file.  This tag is here to verify the validity
  58. of the otag file.  If the first tag is not OT_FileIdent, or the
  59. OT_FileIdent tag value is not the size of the otag file, the otag
  60. file is invalid, so don't attempt to use it.  If the file is valid,
  61. copy the entire file into a buffer.
  62.  
  63. The tags from the otag file have a special OT_Indirect bit.  If this
  64. bit is set, the tag's value is an indirect reference to data defined
  65. elsewhere in the otag file.  The tag's value is the offset to the
  66. data (in bytes) from the beginning of the otag file.  For example,
  67. the otag file fonts:CGTimes.otag that is on the 2.04 Release disks
  68. contains the tag OT_Family (0x80009003), which has its OT_Indirect
  69. bit set.  The value of the OT_Family tag is 195, meaning that the
  70. data for it--the NULL terminated string ``CG Times''--is located 195
  71. bytes into the otag file.
  72.  
  73. Of course, if an application read the file fonts:CGTimes.otag into a
  74. memory buffer, the ``CG Times'' string would be 195 bytes from the
  75. beginning of the buffer.  The OT_Family tag must point to the
  76. absolute address of its data, so when an application loads an otag
  77. file into memory, it has to resolve the indirection of the
  78. OT_Indirect tags in memory.  The application can do this by adding
  79. the buffer address to each OT_Indirect tag value.
  80.  
  81. 3. Find out the name of the typeface's scaling engine and obtain a
  82. pointer to the engine's GlyphEngine structure.
  83.  
  84. One of the level 1 outline tags is the OT_Engine tag.  This tag
  85. refers to the name of this typeface's scaling engine.  At present
  86. there is only one scaling engine available on the Amiga.  It is named
  87. Bullet.  This is the IntelliFont scaling engine.  The name is left
  88. over from the original implementation of the IntelliFont engine used
  89. on the Amiga.  The scaling engine itself is in its own Exec library,
  90. called bullet.library.  To open the engine, build a complete library
  91. name by adding the string ``.library'' to the OT_Engine string, and
  92. open it with OpenLibrary().  Don't assume that OT_Engine will always
  93. be the string ``bullet''.  In the future, Commodore or some third
  94. party developer may create additional scaling engines libraries that
  95. will allow the Amiga to use other types of outline typefaces
  96. (PostScript, Nimbus-Q, etc.).  Using the proper library name will
  97. help ensure compatibility with future possible scaling engines.
  98.  
  99. All scaling engine libraries contain several functions:
  100.  
  101. OpenEngine()                  If successful, returns a pointer to
  102.                                the library's GlyphEngine structure.
  103. CloseEngine()                 Releases the GlyphEngine structure
  104.                                obtained in OpenEngine().
  105. SetInfo()/SetInfoA()          Sets current parameters of a scaling
  106.                                engine (the current typeface, the
  107.                                current point size, the current output
  108.                                resolution, etc.)
  109. ObtainInfo()/ObtainInfoA()    Queries a scaling engine for glyph
  110.                                information (a glyph's bitmap, the
  111.                                kerning value between two glyphs, etc.).
  112. ReleaseInfo()/ReleaseInfoA()  Releases data obtained with
  113.                                ObtainInfo()/ObtainInfoA().
  114.  
  115. To obtain a pointer to a GlyphEngine structure for a particular
  116. scaling library, use that library's OpenEngine() routine.  The
  117. function takes no arguments.
  118.  
  119. 4. Tell the engine which typeface to use.
  120.  
  121. Setting a scaling engine's current typeface involves the SetInfoA()
  122. (or SetInfo()) function and the Level 0 tags from
  123. <diskfont/diskfonttag.h>.  The SetInfoA() function takes two
  124. parameters, a pointer to the GlyphEngine structure, and a tag list of
  125. level 0 outline tags.  The Level 0 tags act as commands for a scaling
  126. engine, some of which are for setting scaling engine parameters (with
  127. SetInfo() or SetInfoA()), and some of which are for querying
  128. information from a scaling engine (with ObtainInfo() or
  129. ObtainInfoA()).
  130.  
  131. Two tags set a scaling engine's current typeface: OT_OTagPath and
  132. OT_TagList.  The OT_OTagPath tag points to the full path name of a
  133. typeface's otag file (for example, fonts:CGTimes.otag).  The
  134. OT_OTagList tag points to the tag list created in step 2 above.
  135.  
  136. 5. Set other scaling engine parameters.
  137.  
  138. There are three other parameters the scaling engine needs in order
  139. answer queries for information:
  140.  
  141.    OT_DeviceDPI            OT_PointHeight          OT_GlyphCode
  142.  
  143. The OT_DeviceDPI tag refers to the resolution of the output device.
  144. The tag value's high word is the horizontal resolution and the low
  145. word is the vertical resolution.  Both are unsigned words measured in
  146. dots per inch.
  147.  
  148. The OT_PointHeight tag refers to the height of a typeface in points.
  149. One point is approximately equal to 1/72 of an inch
  150. (AGFA/Compugraphic defines the point to be 0.01383 inches).  For CG
  151. typefaces, this height is the distance between baselines from one
  152. line to the next (without any leading adjustments).  The point height
  153. is represented as a fixed point, two's complement binary number, with
  154. the point situated in the middle of a long word.  This means the
  155. lower word is the fractional portion and the upper word the whole
  156. number portion (the number covers the powers of two from 215 through
  157. 2-16).
  158.  
  159. For those who may not know, a two's complement number is a way of
  160. representing negative numbers.  To find the two's complement of a
  161. negative number, find the one's complement of the absolute value of
  162. that number (change all the binary ones to zeros and all the zeros to
  163. ones) and then add one to the result.  To change from two's
  164. complement, subtract one from the two's complement number and find
  165. the one's complement of the number.  For example,
  166.  
  167. Before conversion to two's complement, the absolute value of the one
  168. byte decimal quantity -32 is represented as:
  169.  
  170.     In binary         0010 0000  ($20)
  171.     One's complement  1101 1111  ($DF)
  172.     Add One           0000 0001  ($01)
  173.     -----------------------------------
  174.     Two's complement  1110 0000  ($E0)
  175.  
  176. So the number -32 is encoded as 1110 0000 or 0xE0 in hex.  Notice
  177. that the high bit (the sign bit) of the encoded number is set if the
  178. number is negative.  If the number is zero or greater, the high bit
  179. is clear.  This procedure is independent of where the ``point'' is in
  180. the negative number (the ``point'' in this case is the divider
  181. between the whole portion of the number and the fractional portion).
  182. When the computer adds one to the one's complement, it does not
  183. consider where the ``point'' is in the one's complement, the computer
  184. just treats the one's complement value as a whole integer.  For
  185. example, to encode the decimal quantity -531/256 as a two byte, fixed
  186. point, two's complement binary number where the point is situated in
  187. the middle of the two bytes:
  188.  
  189. 531/256 = -(2 + 19/256) = -2.13 in hex
  190.  
  191. In binary           0000 0010.0001 0011   ($02.13 in hex, with the point)
  192.  
  193. One's complement    1111 1101 1110 1100   ($FDEC  in hex ignore the point from now on)
  194. Add One             0000 0000 0000 0001   ($0001)
  195. ----------------------------------------
  196. Two's complement    1111 1101 1110 1101   ($FDED)
  197.  
  198. Notice that the one added to the one's complement is in the 2-8 (=
  199. 1/256) column.
  200.  
  201. The OT_GlyphCode tag refers to the current glyph.  When an
  202. application asks the scaling engine to rasterize a glyph, this is the
  203. glyph the engine renders.  The scaling engine uses Unicode encoding
  204. to represent glyphs.  Unicode is an international character encoding
  205. standard that encompasses many of the world's national scripts in a
  206. 16-bit code space.  Conveniently, the Amiga's Latin-1, 8-bit
  207. character set corresponds to the same glyphs as the Unicode standard.
  208. To set the current glyph to a character from the Amiga character set,
  209. use the same Latin-1 code, but pad it out to a 16-bit value.
  210.  
  211. Because the Compugraphic typefaces use their own character set, the
  212. scaling engine in the bullet.library has to map the Unicode glyph
  213. codes to Compugraphic glyph codes.  Note that the Unicode standard
  214. encompasses many more glyphs than just the Latin-1 character set or
  215. the Compugraphic character set, so many of the characters in the
  216. Unicode set do not map to any glyphs in the Compugraphic set.  For
  217. example, Unicode includes several Asian ideogram sets, that the
  218. Compugraphic set does not.  The result is the vast majority of the
  219. Unicode characters are not available using Compugraphic typefaces.
  220. The Compugraphic character set covers roughly 400 glyphs.  For more
  221. information on the UniCode standard, see the Unicode Consortium's
  222. book The Unicode Standard, Worldwide Character Encoding published by
  223. Addison-Wesley (ISBN 0-201-56788-1).
  224.  
  225.  
  226. Rasterizing a Glyph
  227.  
  228. Once an application has set up the scaling engine, obtaining a glyph
  229. is a matter of asking for it.  As was mentioned earlier, the
  230. ObtainInfoA()/ObtainInfo() function queries a scaling engine for
  231. glyph information.  This function accepts a pointer to a GlyphEngine
  232. structure and a tag list.  To ask for a rasterization of a glyph,
  233. pass ObtainInfo() the OT_GlyphMap tag.  The engine expects the
  234. OT_GlyphMap value to be an address where it can place the address of
  235. a GlyphMap structure.  The GlyphMap structure (defined in
  236. <diskfont/glyph.h>) is for reading only and looks like this:
  237.  
  238. struct GlyphMap {
  239.     UWORD  glm_BMModulo;    /* # of bytes in row: always multiple of 4 */
  240.     UWORD  glm_BMRows;      /* # of rows in bitmap */
  241.     UWORD  glm_BlackLeft;   /* # of blank pixel columns at left of glyph */
  242.     UWORD  glm_BlackTop;    /* # of blank rows at top of glyph */
  243.     UWORD  glm_BlackWidth;  /* span of non-blank columns (horizontal span of the glyph) */
  244.     UWORD  glm_BlackHeight; /* span of non-blank rows (vertical span of the glyph) */
  245.     FIXED  glm_XOrigin;     /* distance from upper left corner of bitmap to lower */
  246.     FIXED  glm_YOrigin;     /*   left of glyph (baseline), in fractional pixels */
  247.     WORD   glm_X0;          /* approximation of XOrigin in whole pixels */
  248.     WORD   glm_Y0;          /* approximation of YOrigin in whole pixels */
  249.     WORD   glm_X1;          /* approximation of XOrigin + Width */
  250.     WORD   glm_Y1;          /* approximation of YOrigin + Width */
  251.     FIXED  glm_Width;       /* character advance, as fraction of em width */
  252.     UBYTE *glm_BitMap;      /* actual glyph bitmap */
  253. };
  254.  
  255. The glm_BitMap field points to a single bitplane bitmap of the glyph.
  256. This bitmap is not necessarily in Chip RAM, so if an application
  257. needs to use the blitter to render the glyph, it has to copy the
  258. bitmap to a Chip RAM buffer.  The fields glm_BMModulo and glm_BMRows
  259. are the dimensions of the whole bitmap.  The glyph itself does not
  260. occupy the entire bitmap area.  The fields glm_BlackLeft,
  261. glm_BlackTop, glm_BlackWidth, and glm_BlackHeight describe the
  262. position and dimension of the glyph within the bitmap.  The fields
  263. glm_XOrigin and glm_YOrigin are the X and Y offsets from the bitmap's
  264. upper left corner to the glyph's lower left corner.  The lower left
  265. corner lies on the glyph's baseline.  These X and Y offsets are in
  266. fractional pixels.  The fields glm_X0 and glm_Y0 are rounded versions
  267. of glm_XOrigin and glm_YOrigin, respectively.
  268.  
  269. The glm_Width field is a measure of the width of the glyph in
  270. fractions of an em (pronounced like the letter 'M').  This value is a
  271. fixed point binary fraction.  The em is a relative measurement.  A
  272. distance of one em is equal to the point size of the typeface.  For
  273. example, in a 36 point typeface, one em equals 36 points which is
  274. approximately equal to a half inch.  For a 72 point typeface, one em
  275. equals 72 points which is approximately equal to one inch.
  276.  
  277. When an application is finished with the GlyphMap structure, it must
  278. use the ReleaseInfoA() or ReleaseInfo() function to relinquish the
  279. GlyphMap structure.  This function uses the same format as
  280. ObtainInfoA()/ObtainInfo(), except the data value of the OT_GlyphMap
  281. tag is a pointer to the GlyphMap structure (rather than a pointer to
  282. a pointer).
  283.  
  284.  
  285. Kerning
  286.  
  287. The IntelliFont scaling engine also supports two types of kerning.
  288. One type of kerning is called text kerning, which is for regular
  289. bodies of text.  The other type of kerning is called design kerning,
  290. which is for more obvious displays, like headlines.  The basic
  291. difference is that design kerning is generally more tightly spaced
  292. than text kerning.
  293.  
  294. Before asking for a kerning pair, an application has to tell the
  295. engine which character pair to kern.  It does this using one of the
  296. SetInfo() functions to set the primary glyph, OT_GlyphCode, and the
  297. secondary glyph code, OT_GlyphCode2.
  298.  
  299. To ask the scaling engine for a kerning value, use one of the
  300. ObtainInfo() functions with the OT_TextKernPair (for text kerning) or
  301. OT_DesignKernPair (for design kerning) tags.  The engine expects the
  302. value of the kerning tag to be an address where it can store a four
  303. byte long kerning value.  The kerning value is a fixed point binary
  304. fraction of an em square (like the glm_Width field from the GlyphMap
  305. structure).  This value is the distance to remove from the primary
  306. character advance (the glm_Width of OT_GlyphCode) when rendering the
  307. secondary glyph (OT_GlyphCode2) immediately following the primary
  308. glyph.
  309.  
  310. Unlike other ObtainInfo() tags, the scaling engine does not allocate
  311. any resources when answering queries about kerning values.
  312. Applications do not have to use ReleaseInfo() functions for kerning
  313. queries made with either OT_TextKernPair or OT_DesignKernPair.
  314.  
  315.  
  316. Width Lists
  317.  
  318. An application can find the widths of a typeface's glyphs using the
  319. OT_WidthList tag with one of the ObtainInfo() functions.  The engine
  320. expects the OT_WidthList value to be an address where it can place
  321. the address of a MinList structure.  This MinList points to a list of
  322. GlyphWidthEntry structures.  The GlyphWidthEntry structure (defined
  323. in <diskfont/glyph.h>) is for reading only and looks like this:
  324.  
  325. struct GlyphWidthEntry {
  326.     struct MinNode gwe_Node;  /* on list returned by OT_WidthList inquiry */
  327.     UWORD          gwe_Code;  /* entry's character code value */
  328.     FIXED          gwe_Width; /* character advance, as fraction of em width */
  329. };
  330.  
  331. The MinList contains an entry for each valid Unicode glyph ranging
  332. from the primary glyph, OT_GlyphCode, through the secondary glyph,
  333. OT_GlyphCode2.  The engine does not create a GlyphWidthEntry
  334. structure for codes without glyphs (for example the codes before the
  335. space character in the Latin-1 character set).
  336.  
  337. When an application is finished with the width list, it must use one
  338. of the ReleaseInfo() functions to relinquish the list.  This function
  339. uses the same format as the ObtainInfo() functions, except the data
  340. value of the OT_WidthList tag is a pointer to the MinList (rather
  341. than a pointer to a pointer).  The primary and secondary code values
  342. do not have to remain constant while an application is using a width
  343. list.  The engine deallocates the width list resources independently
  344. of the primary and secondary code values, so these can change after
  345. obtaining a width list.
  346.  
  347. The following code fragment asks the scaling engine, ge, for a list
  348. of character widths of the Unicode glyphs ranging from unicode
  349. (OT_GlyphCode) to unicode2 (OT_GlyphCode2), inclusive.  The fragment
  350. steps through the list of widths, printing each one.
  351.  
  352.  
  353. struct MinList *widthlist;
  354. struct GlyphWidthEntry *widthentry;
  355. .  .  .
  356.  
  357. if (SetInfo(ge,
  358.             OT_GlyphCode,   unicode,
  359.             OT_GlyphCode2,  unicode2,
  360.             TAG_END) == OTERR_Success)
  361. {
  362.     if (ObtainInfo(ge, OT_WidthList, &widthlist, TAG_END) == OTERR_Success)
  363.     {
  364.         for (widthentry = (struct GlyphWidthEntry *) widthlist->mlh_Head;
  365.             widthentry->gwe_Node.mln_Succ;
  366.             widthentry = (struct GlyphWidthEntry *)
  367.             widthentry->gwe_Node.mln_Succ)
  368.         {
  369.             printf("$%lx: %ld.%ld\n",
  370.                 widthentry->gwe_Code,
  371.                 widthentry->gwe_Width>>16,
  372.                 ((widthentry->gwe_Width&0xffff)*10000)>>16);
  373.         }
  374.         ReleaseInfo(ge, OT_WidthList, widthlist, TAG_END);
  375.     }
  376. }
  377. .  .  .
  378.  
  379.  
  380. Notice that the ObtainInfo() functions (as well as the SetInfo()
  381. functions) return an error code (the error codes are defined in
  382. <diskfont/oterrors.h>).  If that error code is equal to
  383. OTERR_Success, the operation was successful.
  384.  
  385.  
  386. Rotating
  387.  
  388. Taking advantage of other features of the Bullet library is a matter
  389. of setting other engine parameters using one of the SetInfo()
  390. functions with some other level 0 tags.  One interesting feature of
  391. the IntelliFont engine is its ability to rotate glyphs.  By setting
  392. the OT_RotateSin and OT_RotateCos values, the IntelliFont engine can
  393. rotate a glyph's baseline from the glyph origin (the glm_XOrigin and
  394. glm_YOrigin from the GlyphMap structure).
  395.  
  396. The OT_RotateSin and OT_RotateCos are, respectively, the sine and
  397. cosine of the baseline rotation angle.  The engine can rotate to any
  398. angle.  The sine and cosine must correspond to the same angle and
  399. must be in the sine and cosine value range (0 through 1 inclusive).
  400. The engine does not do any error checking on the sine and cosine
  401. values.  As a result, the engine will yield strange results if the
  402. sine and cosine are from very different angles or if these values are
  403. out of range for sines and cosines (greater than 1).  By default, the
  404. engine sets these values to 0.0 and 1.0, the sine and cosine of 0
  405. degrees.  These values are encoded as fixed point binary fractions
  406. (the negative values are two's complement).
  407.  
  408. When setting the baseline rotation, an application must set both the
  409. sine and cosine.  It must set OT_RotateSin first, then OT_RotateCos.
  410. An application can set both values in the same SetInfo() function,
  411. but the sine must come first.  For example, to set the rotation angle
  412. to 150 degrees:
  413.  
  414. The sine of 150 degrees is 0.5 which is 0x00008000 in hex.  The
  415. cosine of 150 degrees is approximately -0.866 which is approximately
  416. 0xffff224c in hex (two's complement), so:
  417.  
  418. .  .  .
  419.  
  420. if (SetInfo(ge,
  421.             OT_RotateSin, 0x8000,
  422.             OT_RotateCos, 0xFFFF224C,
  423.             TAG_END) == OTERR_Success) /* If SetInfo() returns OTERR_Success, */
  424.                                        /* it worked OK. */
  425. {   /* The baseline rotation has been set, now the application can render it. */
  426.  
  427.     .  .  .
  428.  
  429.  
  430. Shearing
  431.  
  432. Like baseline rotation, glyph shearing (also known as italicizing) is
  433. a matter of setting some Level 0 tags.  The shearing tags,
  434. OT_ShearSin and OT_ShearCos, specify the shearing angle, or the angle
  435. at which the typeface is italicized.  This angle refers to the angle
  436. that results from rotating the vertical axis clockwise.  The angle
  437. can range from -45 to 45 degrees (inclusive).  Like the rotation
  438. angle, the shearing angle is represented as a sine and cosine value
  439. that must correspond to the same angle and must fall into normal
  440. bounds for sine and cosine values.  Also like the rotation angle sine
  441. and cosine tags, an application must set both the OT_ShearSin and
  442. OT_ShearCos tags, in that order.  By default, the shearing value is
  443. zero degrees meaning there is no shearing (OT_ShearSin = 0x00000000,
  444. OT_ShearCos = 0x00010000).
  445.  
  446.  
  447. Other Level 0 Tags
  448.  
  449. There are several other Level 0 tags:
  450.  
  451. OT_DotSize.  This tag specifies the X and Y size of the target
  452. device's dots.  The X and Y DPI imply a dot size.  For example, at
  453. 300 X and 300 Y DPI, the resolution implied dot size is 1/300 inches
  454. by 1/300 inches.  For some devices (like some dot matrix printers),
  455. the size of the output dot does not match its resolution implied
  456. size.  To a degree, the IntelliFont engine can account for this.  The
  457. dot size is represented as a percentage of the dot's resolution
  458. implied size.  The X percentage is in the tag value's upper word, and
  459. the Y percentage is in the tag value's lower word.
  460.  
  461. OT_SetFactor.  This tag distorts the width of a typeface by changing
  462. the width of the em square.  The scaling engine changes the em width
  463. to this tag's value.  The value is a fixed point binary fraction.
  464.  
  465. OT_EmboldenX/OT_EmboldenY.  These tags specify the algorithmic
  466. emboldening factor in the X and Y direction, respectively.  The tag
  467. values are fixed point two's complement binary numbers.  The units
  468. are measured in ems.  Emboldening values above zero embolden the
  469. typeface.  Emboldening values below zero lighten the typeface.  By
  470. default, both values are zero.
  471.  
  472. OT_GlyphWidth.  This tag's value specifies a width for the current
  473. typeface.  It is a fraction of an em represented as a fixed point
  474. binary number.  If this value is set to something besides 0.0, all
  475. glyphs will have this width.  To turn off the constant width, set
  476. OT_GlyphMap back to 0.0 (its default value).
  477.  
  478.  
  479. The Otag File Tags
  480.  
  481. The Outline Tag (otag) file contains a number of tags that describe a
  482. font outline to the Diskfont library.  The purpose of most of these
  483. tags is to allow Diskfont to attribute styles to a typeface when
  484. loading a font outline as a standard Amiga system font.  Most
  485. applications that use the scaling engine will not need to worry about
  486. the meaning of the majority of these tags, but they are described
  487. below.  The following tags are Level 1 tags and must be present in
  488. every otag file:
  489.  
  490. OT_FileIdent.  Every valid otag file starts with this tag.  Its value
  491. is the size of the file.  It doesn't really have anything to do with
  492. the definition of the typeface, but it does serve as a way to check
  493. the validity of the otag file.
  494.  
  495. OT_Engine.  This tag's value points to a string naming the font
  496. scaling engine.  For example, the OT_Engine tag in fonts:CGTimes.otag
  497. is ``bullet''.
  498.  
  499. OT_Family.  This tag's value points to a string naming the typefaces
  500. font family.  For example, the OT_Family in fonts:CGTimes.otag is
  501. ``bullet''.
  502.  
  503. OT_SymbolSet.  This tag's value is a two byte ASCII code for this
  504. typeface's symbol set.  This tells the system which symbol set to use
  505. to map the Amiga character set to the Compugraphic character set.
  506. The symbol set for most CG fonts designed for use with the Amiga is
  507. ``L1'', which stands for Latin1.  The exception is the CG fonts from
  508. Gold Disk, Inc.  They use the ``GD'' (Gold Disk) symbol set.
  509.  
  510. OT_YSizeFactor.  For traditional Amiga fonts, the font size does not
  511. include any spacing on top or bottom of the typeface--the Amiga
  512. doesn't consider it part of the font.  CG fonts include spacing on
  513. the top and bottom of their typefaces.  This tag's value is a ratio
  514. of the point height of a typeface to its ``black'' height (the point
  515. height minus the space on the typeface's top and bottom).  The high
  516. word is the point height factor and the low word is the black height
  517. factor.  Note that these values form a ratio.  Individually, they do
  518. not necessarily reflect any useful value.
  519.  
  520. OT_SerifFlag.  If this tag's value is TRUE, this typeface has serifs.
  521.  
  522. OT_StemWeight.  This tag's value can be anywhere from 0 through 255
  523. and indicates a nominal weight or ``boldness'' to the typeface.  The
  524. <diskfont/diskfonttag.h> include file defines a set of ratings for
  525. this tag's value.  See that file for more details.  When the Diskfont
  526. library opens an outline font, it uses this value to determine if a
  527. typeface is bold.
  528.  
  529. OT_SlantStyle.  The <diskfont/diskfonttag.h> include file defines a
  530. set of three possible values for this tag's value.  See that file for
  531. more details.  When the Diskfont library opens an outline font, it
  532. uses this value to determine if a typeface is italicized/obliqued.
  533.  
  534. OT_HorizStyle.  This tag's value can be anywhere from 0 through 255
  535. and indicates a nominal width rating to the typeface.  The
  536. <diskfont/diskfonttag.h> include file defines a set of ratings for
  537. this tag's value.  See that file for more details.  When the Diskfont
  538. library opens an outline font, it uses this value to determine if a
  539. typeface is extended.
  540.  
  541. OT_AvailSizes.  This tag's value points to a sorted list of UWORDs.
  542. The first UWORD is the number of entries in the sorted list.  The
  543. remaining UWORDs are the font sizes that the Diskfont library lists
  544. when calling AvailFonts().
  545.  
  546. OT_SpecCount.  This tag's value is a number of spec tags that follow
  547. it.  A spec tag is private to the scaling engine.
  548.  
  549.  
  550. The following are Level 2 tags.  They may also be in an otag file but
  551. are not required:
  552.  
  553. OT_BName.  This tag points to a string naming the bold variant of
  554. this typeface.  For example, the fonts:CGTimes.otag file lists
  555. ``CGTimesBold'' as its bold variant.
  556.  
  557. OT_IName.  This tag points to a string naming the italic variant of
  558. this typeface.
  559.  
  560. OT_BIName.  This tag points to a string naming the bold italic
  561. variant of this typeface.
  562.  
  563. OT_SpaceWidth.  This tag's value is the width of the space character
  564. at 250 points (where there are 72.307 points in an inch).  The width
  565. is in Design Window Units (DWUs).  One DWU is equal to 1/2540 inches.
  566. To convert to X pixels:
  567.  
  568.  
  569.     OT_SpaceWidth   pointsize
  570.     ------------- * --------- *  XDPI = spacewidth in pixels (X dots)
  571.         2540           250
  572.  
  573. OT_IsFixed.   If this tag's value is TRUE, every glyph in this
  574. typeface has the same character advance (a fixed width).
  575.  
  576. OT_InhibitAlgoStyle.  This tag's value is a bitmask that is
  577. compatible with the ta_Style field of the TextAttr structure (defined
  578. in <graphics/text.h>).  This tag tells which styles cannot be added
  579. to a typeface algorithmically.  For example, if the FSF_BOLD bit in
  580. OT_InhibitAlgoStyle is set and a user asks for a bold version of the
  581. typeface, the diskfont.library (or an application) can add that style
  582. algorithmically.
  583.  
  584.  
  585. At present there are no Level 3 tags.
  586.  
  587.  
  588. About the Examples
  589.  
  590. This article contains two code examples.  The first, Rotate, rotates
  591. a user-specified glyph around a central point.  By default, it
  592. rotates a 36 point 'A' using the font fonts:CGTimes.font.  If Rotate
  593. finds an AmigaDOS environment variable called ``XYDPI'', it will use
  594. the X and Y DPI it finds in that variable as the default target
  595. device DPI (see the description of the Level 0 OT_DeviceDPI tag).  If
  596. that variable is not defined, Rotate will use an XDPI of 68 and a
  597. YDPI of 27 which, nominally, is the X and Y DPI of a standard Hires
  598. display.
  599.  
  600. The second example, View, displays a file using the same defaults as
  601. Rotate.  View utilizes kerning pairs to display its glyphs.  Because
  602. View only considers ``visible'' characters, it ignores characters
  603. that have widths but no glyph.  The result is, View doesn't print any
  604. space characters.  If View were smarter, it would ask the scaling
  605. engine for a width list so it could properly advance the current
  606. pointer when it comes across a space or some other character without
  607. a glyph.
  608.  
  609. Notice that View uses a slightly modified version of BulletMain.c
  610. called BulletMainFile.c.  Only BulletMain.c appears in the example
  611. code.  The only significant difference between the two is that
  612. BulletMainFile.c obtains a file name for View to display.
  613.